<?php
/*
* Copyright (c) 2010 by Cediti
*
* You may distribute under the terms of either the GNU Lesser General
* Public License or the new BSD License, as specified in the README file.
*/
// created :	31 March 2010
// version :    19 April 2010

class Cmis_Http_Adapter_Curl extends Cmis_Http_Adapter
{
	protected $_curl = null;

	public function setOption($key, $value)
	{
        if (!empty($value) && is_resource($this->_curl))
        {
            curl_setopt($this->_curl, $key, $value);
        }

        return parent::setOption($key, $value);
	}

	protected function _preRequest($method, $data, $mimeType, $extras)
    {
    	if (!is_resource($this->_curl))
    	{
    		$this->_initCurl();
    	}

        //set method
        switch ($method)
        {
            case self::METHOD_GET:
                curl_setopt($this->_curl, CURLOPT_HTTPGET, true);
                $this->_return_type = 'atom';
                break;
            case self::METHOD_POST:
                curl_setopt($this->_curl, CURLOPT_POST, true);
                curl_setopt($this->_curl, CURLOPT_POSTFIELDS, $data);
                $this->_return_type = 'cmis';
                break;
            case self::METHOD_DELETE:
                curl_setopt($this->_curl, CURLOPT_CUSTOMREQUEST, $method);
                break;
            case self::METHOD_PUT:
                curl_setopt($this->_curl, CURLOPT_PUT, true);
                 die('-[Must be implemented : ' . __METHOD__ . ' (' . __FILE__ . '#' . __LINE__ . ')]-');
                break;
            default:
                curl_setopt($this->_curl, CURLOPT_CUSTOMREQUEST, $method);
                 die('-[Must be implemented : ' . __METHOD__ . ' (' . __FILE__ . '#' . __LINE__ . ')]-');
                break;
        }

        //set header
        //specific headers first
        $headers = $this->getHeader();
        if (isset($headers['Cookie']))
        {
            curl_setopt($this->_curl, CURLOPT_COOKIE, $value);
            unset($headers['Cookie']);
        }

        if (isset($headers['Referer']))
        {
            curl_setopt($this->_curl, CURLOPT_REFERER, $value);
            unset($headers['Referer']);
        }

        if (isset($headers['User-Agent']))
        {
            curl_setopt($this->_curl, CURLOPT_USERAGENT, $value);
            unset($headers['User-Agent']);
        }

        //other header
        if (!empty($headers))
        {
        	$_headers;
        	foreach($headers as $header => $value)
        	{
        		$_headers[] = $header . ': ' . $value;
        	}
            curl_setopt($this->_curl, CURLOPT_HTTPHEADER, $_headers);
        }
    }

    protected function _request($method, $url, $data, $mimeType, $extras)
    {
        //url
        curl_setopt($this->_curl, CURLOPT_URL, $url);

    	$response = curl_exec($this->_curl);

    	//check for bad answer
    	if ($response === false || is_null($response))
    	{
    		$errno = curl_errno($this->_curl);
    		$error = curl_error($this->_curl);
    		$this->_setError($errno, $error);

    		switch($errno)
    		{
    			case CURLE_COULDNT_CONNECT :
    				//Failed to connect() to host or proxy.
    				throw new Cmis_Exception_Host_Unreachable($error, $errno);
    				break;
    			default:
    				throw new Cmis_Exception_Http('HTTP ERROR : ' . $error, $errno);
    		}
    	}
        $this->_infos = curl_getinfo($this->_curl);

        return $response;
    }

    /**
     * Method to be ovewritten by subclass
     * @return void
     */
    protected function _postRequest($method, $url, $data, $mimeType, $extras)
    {
        $this->close();
    }

    protected function _auth($method, $url, $data, $mimeType, $extras)
    {
    	if (Cmis_Request_Interface::AUTH_HTTP_BASIC == $this->_auth_type)
    	{
    		$this->setOption(CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
    		$this->setOption(CURLOPT_USERPWD, $this->_auth_login . ':' . $this->_auth_password);
    	}
    	else
    	{
    		return false;
    	}
    	return true;
    }

    protected function _initCurl()
    {
    	$this->_curl = curl_init();
    	$options = $this->getOptions();
    	if (!empty($options))
    	{
    		curl_setopt_array($this->_curl, $options);
    	}
    	else
    	{
    		$this->setOption(CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
    		$this->setOption(CURLOPT_CONNECTTIMEOUT, self::TIMEOUT);
    		$this->setOption(CURLOPT_FOLLOWLOCATION, true);
    	}
    }

    protected function _reset()
    {
        $this->setOption(CURLOPT_RETURNTRANSFER, true);
        $this->setOption(CURLOPT_HEADER, true);

        if ($this->_secure)
        {
        	$this->setOption(CURLOPT_SSL_VERIFYPEER, true);
        	$this->setOption(CURLOPT_SSL_VERIFYHOST, true);
        }
    }

    public function close()
    {
        if (!is_resource($this->_curl))
        {
            $this->_initCurl();
        }
        curl_close($this->_curl);

        return $this;
    }
}

# EOF
